﻿using FileStorage.Common;
using FileStorage.Models.Entity;
using System;
using System.Collections.Generic;
using System.Linq;

namespace FileStorage.Models
{
    public static class FolderDao
    {
        public static Folder queryById(string fid, DapperHelper cn)
        {
            return cn.FirstOrDefault<Folder>("SELECT * FROM `fs_folder` WHERE FolderId = @fid;", new { fid });
        }

        public static List<Folder> getParentList(string fid, DapperHelper cn)
        {
            var f = queryById(fid, cn);
            List<Folder> folderList = new List<Folder>();
            if (f != null)
            {
                while (f.FolderParent != "null" && folderList.Count < int.MaxValue)
                {
                    f = queryById(f.FolderParent, cn);
                    folderList.Add(f);
                }
            }

            folderList.Reverse();
            return folderList;
        }

        public static long countByParentId(string fid, DapperHelper cn)
        {
            // return cn.FirstOrDefault<long>("SELECT COUNT(FolderId) FROM `fs_folder` WHERE FolderParent = @fid AND FolderDeletionDate IS NULL;", new { fid });
            return cn.FirstOrDefault<long>("SELECT COUNT(FolderId) FROM `fs_folder` WHERE FolderParent = @fid;", new { fid });
        }

        public static List<Folder> queryByParentIdSection(string pid, long offset, int rows, DapperHelper cn)
        {
            return cn.Query<Folder>("SELECT * FROM `fs_folder` WHERE FolderParent = @pid AND FolderDeletionDate IS NULL limit @offset,@rows;", new { pid, offset, rows }).ToList();
        }

        public static List<Folder> queryByParentId(string pid, DapperHelper cn)
        {
            return cn.Query<Folder>("SELECT * FROM `fs_folder` WHERE FolderParent = @pid AND FolderDeletionDate IS NULL limit 0,2147483647;", new { pid }).ToList();
        }

        public static bool updateFolderConstraintById(string folderId, int newConstraint, DapperHelper cn)
        {
            return cn.ExecuteSql("UPDATE `fs_folder` SET FolderConstraint = @newConstraint WHERE FolderId = @folderId;", new { folderId, newConstraint });
        }

        public static void changeChildFolderConstraint(string folderId, int newConstraint, DapperHelper cn)
        {
            List<Folder> cfs = queryByParentId(folderId, cn);
            foreach (Folder cf in cfs)
            {
                if (cf.FolderConstraint < newConstraint)
                    updateFolderConstraintById(cf.FolderId, newConstraint, cn);
                changeChildFolderConstraint(cf.FolderId, newConstraint, cn);
            }
        }

        public static bool updateFolderNameById(string folderId, string newName, DapperHelper cn)
        {
            return cn.ExecuteSql("UPDATE `fs_folder` SET FolderName = @newName WHERE FolderId = @folderId;", new { folderId, newName });
        }

        public static bool deleteById(string folderId, DapperHelper cn)
        {
            return cn.ExecuteSql("DELETE FROM `fs_folder` WHERE FolderId = @folderId;", new { folderId });
        }

        public static bool deleteFolder(string folderId, string account, DapperHelper cn)
        {
            return cn.ExecuteSql("UPDATE `fs_folder` SET FolderDeletionDate = @date,FolderDeletor = @account WHERE FolderId = @folderId;", new { date = SystemUtil.accurateToDay(), account, folderId });
        }

        public static bool isValidFolder(Folder f, string account, DapperHelper cn)
        {
            List<Folder> repeats = queryByParentId(f.FolderParent, cn).Where(x => x.FolderName == f.FolderName).ToList();
            if (queryById(f.FolderParent, cn) == null || repeats.Count > 1)
            {
                deleteAllChildFolder(f.FolderId, account, cn);
                // deleteAllChildByFolderId(f.FolderId, cn);
                return false;
            }
            return true;
        }

        public static void deleteAllChildFolder(string folderId, string account, DapperHelper cn)
        {
            List<Folder> cf = queryByParentId(folderId, cn);
            foreach (Folder f in cf)
                deleteAllChildFolder(f.FolderId, account, cn);
            List<Node> files = FileDao.queryByParentFolderId(folderId, cn);
            foreach (Node f2 in files)
                FileDao.deleteNode(f2, account, cn);
            deleteFolder(folderId, account, cn);
        }

        public static void deleteAllChildByFolderId(string folderId, DapperHelper cn)
        {
            List<Folder> cf = queryByParentId(folderId, cn);
            foreach (Folder f in cf)
                deleteAllChildByFolderId(f.FolderId, cn);
            List<Node> files = FileDao.queryByParentFolderId(folderId, cn);
            foreach (Node f2 in files)
                FileDao.deleteById(f2.FileId, cn);
            deleteById(folderId, cn);
        }
    }
}
